#ifndef CU_DEBUG_H_
#define CU_DEBUG_H_

#include "cu.h"
#include "CuString.h"
#include "CuVector.h"

class CuDebugData
{
public:
    __device__ CuDebugData();
    __device__ ~CuDebugData();

    int ref;
    CuVector<CuString> strs;
};

class CuDebug
{
public:
    __device__ CuDebug(const CuDebug& other);
    __device__ void operator=(const CuDebug& other);
    __device__ ~CuDebug();

    CuDebugData *data;

protected:
    __device__ friend CuDebug cuDebug();
    __device__ CuDebug();
};

__device__ CuDebug cuDebug();
__device__ CuDebug operator<<(CuDebug dbg, const char* str);
__device__ CuDebug operator<<(CuDebug dbg, int num);
__device__ CuDebug operator<<(CuDebug dbg, uint32_t num);
__device__ CuDebug operator<<(CuDebug dbg, int64_t num);
__device__ CuDebug operator<<(CuDebug dbg, uint64_t num);
__device__ CuDebug operator<<(CuDebug dbg, const CuString &str);

template<class T>
__device__ CuDebug operator<<(CuDebug dbg, const CuVector<T>& vec)
{
    dbg << "[";
    for(int i = 0; i < vec.size(); i++)
    {
        dbg << vec[i];
        if (i != vec.size() - 1)
        {
            auto &back = dbg.data->strs.back();
            back = back + ", ";
        }
    }
    dbg << "]";
    return dbg;
}


#endif // !CU_H_
